#ifndef DXF_TOOLS_H
#define DXF_TOOLS_H
#include <vector>
#include <QObject>
#include <memory>
#include <map>
#include <list>
#include <qlist.h>
#include <QDebug>

enum shape_type{
    t_undef ,
    t_layer ,
    t_point ,
    t_line ,
    t_poly_line ,
    t_arc ,
    t_circ,
    t_spline ,
    t_end
};

struct  point_{
    double m_x  ;
    double m_y  ;
    double m_z  ;
    double m_bulge  ;
    double m_w ;
};

class  mate_shape{
public :
    int m_type  ;
    mate_shape(){
        m_type = t_undef;
    }
    virtual void fun_show(){
        qDebug() << " mate_shape " ;
    }
};

class  shape_layer : public mate_shape  {
public :
    shape_layer():mate_shape(){
        m_type = t_layer ;
    }
    std::string m_name  ;

    void fun_show(){
        qDebug() << " shape_layer " << m_name.c_str() ;
    }
};

class  shape_point : public mate_shape  {
public :
    shape_point():mate_shape(){
        m_type = t_point ;
    }
    point_ m_point ;

    void fun_show(){
        qDebug() << " shape_point "
                 << m_point.m_x
                 << m_point.m_y
                 << m_point.m_z ;
    }
};

class  shape_line : public mate_shape  {
public :
    shape_line():mate_shape(){
        m_type = t_line ;
    }
    point_ m_point_start ;
    point_ m_point_end  ;

    void fun_show(){
        qDebug() << " shape_line "
                 << m_point_start.m_x
                 << m_point_start.m_y
                 << m_point_start.m_z
                 << "  "
                 << m_point_end.m_x
                 << m_point_end.m_y
                 << m_point_end.m_z ;
    }
};


class  shape_poly_line : public mate_shape  {
public :
    shape_poly_line():mate_shape(){
        m_type = t_poly_line ;
    }
    std::vector < point_ > m_points ;

    void fun_show(){
        qDebug() << " shape_poly_line "
                 << m_points.size() ;
    }
};


class  shape_spline : public mate_shape  {
public :
    shape_spline():mate_shape(){
        m_type = t_spline ;
    }
    std::vector < point_ > m_control_points ;
    std::vector < point_ > m_fit_points     ;
    std::vector < point_ > m_knot_points    ;

    void fun_show(){
        qDebug() << " shape_spline "
                 << m_control_points.size() ;
    }
};

class  shape_arc : public mate_shape  {
public :
    shape_arc():mate_shape(){
        m_type = t_arc ;
    }
    point_ m_point_c   ;
    double m_radius    ;
    double m_angle_1   ;
    double m_angle_2   ;

    void fun_show(){
        qDebug() << " shape_arc "
               <<"m_x     " << m_point_c.m_x
               <<"m_y     " << m_point_c.m_y
               <<"m_z     " << m_point_c.m_z
               <<"adius   " << m_radius
               <<"angle_1 " << m_angle_1
               <<"angle_2 " << m_angle_2      ;
    }
};

class  shape_circ : public mate_shape  {
public :
    shape_circ():mate_shape(){
        m_type = t_circ ;
    }
    point_ m_point_c   ;
    double m_radius    ;

    void fun_show(){
        qDebug() << " shape_circ "
                << " m_x   "  << m_point_c.m_x
                << " m_y   "  << m_point_c.m_y
                << " m_z   "  << m_point_c.m_z
                << "radius "  << m_radius ;
    }
};

class dxf_tools : public QObject
{
    Q_OBJECT
    explicit dxf_tools(QObject *parent = 0);
public:
    static dxf_tools * fun_get_instance(){
        static dxf_tools tools ;
        return  &tools ;
    }

    std::map<std::string ,  QList < mate_shape *  >  > m_all_info;
    void fun_add_shape_by_layer_name(  std::string name , mate_shape * sp  ){
        m_all_info[ name ].append(sp);
    }

    void fun_clean_all(){
//        for(auto it : m_all_info ){
//            qDebug() << it.first.c_str() ;
//            for(auto sp_it : it.second ){
//                delete sp_it ;
//                sp_it = NULL ;
//            }
//        }
        m_curr_type = t_undef ;
        m_all_info.clear() ;
        m_curr_sp = NULL ;
    }
public:

    int m_curr_type ;
    shape_poly_line * m_curr_sp   ;
    shape_spline    * m_curr_splise   ;

signals:

public slots:
};

#define  dxf_tools_inst dxf_tools::fun_get_instance()

#endif // DXF_TOOLS_H
